package com.aacar.op.service.security;

import com.aacar.op.entity.user.User;
import com.aacar.op.service.user.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.subject.SimplePrincipalCollection;


/**
 * shiro身份验证类
 *
 * @author Gongle
 */
public class JdbcAuthenticationRealm extends AuthorizationRealm {

    private IUserService userService;

    /**
     * shiro身份验证回调方法
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        String loginName = usernamePasswordToken.getUsername();

        if (StringUtils.isBlank(loginName)) {
            throw new AccountException("用户名不能为空");
        }

        User user = userService.getByLoginName(loginName);

        if (user == null) {
            throw new UnknownAccountException("账号不存在");
        }
        clearCachedAuthorizationInfo(user.getLoginName());
        ShiroUser shiroUser = new ShiroUser(user);
        shiroUser.setHost(usernamePasswordToken.getHost());

        return new SimpleAuthenticationInfo(shiroUser, user.getPassword(), getName());
    }


    /**
     * 更新用户授权信息缓存.
     */
    public void clearCachedAuthorizationInfo(String principal) {
        SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
        clearCachedAuthorizationInfo(principals);
    }

    /**
     * 清除所有用户授权信息缓存.
     */
    public void clearAllCachedAuthorizationInfo() {
        Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
        if (cache != null) {
            for (Object key : cache.keys()) {
                cache.remove(key);
            }
        }
    }

    public void setUserService(IUserService userService) {
        this.userService = userService;
    }

    public IUserService getUserService() {
        return userService;
    }
}
